package com.softstone.sng.client;

import com.jme3.app.Application;
import com.jme3.app.state.AbstractAppState;
import com.jme3.app.state.AppStateManager;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.softstone.sng.messages.PlayerMessage;
import com.softstone.sng.messages.ManualControlMessage;
import java.io.IOException;
import java.util.LinkedList;
import java.util.concurrent.Callable;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Tomav
 */
public class MainAppState extends AbstractAppState
{

  private Main app;
  Geometry geom;
  LinkedList<ManualControlMessage> messageQueue = new LinkedList<ManualControlMessage>();
  private Vector3f walkDirection = new Vector3f(Vector3f.ZERO);
  private Vector3f directionFront = new Vector3f(Vector3f.UNIT_Z);
  private Vector3f directionLeft = new Vector3f(Vector3f.UNIT_X);
  private Vector3f directionUp = new Vector3f(Vector3f.UNIT_Y.negateLocal());
  private float rotAmountX = 0;
  private float rotAmountY = 0;
  private float walkAmount = 0;
  private float strafeAmount = 0;
  private float verticalAmount = 0;
  private float speed = .05f;
  private static int licznik = 0;

  @Override
  public void initialize(AppStateManager stateManager, Application app)
  {
    super.initialize(stateManager, app);
    this.app = (Main) app;
    this.app.getInputManager().setCursorVisible(false);
    geom = this.app.createMyPlayer();
    this.app.getClient().addMessageListener(new MsgListener(this.app), PlayerMessage.class);
    try
    {
      this.app.getClient().connectToServer("192.168.178.26", 6143, 6143);
      this.app.getClient().start();
    } catch (IOException ex)
    {
      Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
      this.app.stop();
    }
//    this.app.getInputManager().addMapping("spacja", new KeyTrigger(KeyInput.KEY_SPACE));
//    this.app.getInputManager().addListener(new ActionListener(this.app), "spacja");
  }

  @Override
  public void update(float tpf)
  {
    super.update(tpf);
    rotAmountX = 0;
    rotAmountY = 0;
    if (messageQueue.size() != 0)
    {
      Boolean warunek = false;
      do
      {
        licznik++;
        ManualControlMessage m = (ManualControlMessage) messageQueue.poll();
        if ((walkAmount != m.moveZ) || (strafeAmount != m.moveX) || (verticalAmount != m.moveY))
        {
          warunek = true;
          walkAmount = m.moveZ;
          strafeAmount = m.moveX;
          verticalAmount = m.moveY;
        }
        rotAmountX += m.aimX;
        rotAmountY += m.aimY;
      }
      while (!warunek && (messageQueue.size() > 0));
    }
    walkDirection.set(directionFront).multLocal(walkAmount * tpf);
    walkDirection.addLocal(directionLeft.mult(strafeAmount * tpf));
    walkDirection.addLocal(directionUp.mult(verticalAmount * tpf)).normalizeLocal().multLocal(speed);
    final float angleY = (FastMath.PI) * tpf * rotAmountX * 4;
    final float angleX = (FastMath.PI) * tpf * rotAmountY * 2;
    app.enqueue(new Callable<Void>()
    {
      @Override
      public Void call() throws Exception
      {
        geom.rotate(angleX, angleY, 0);
        Vector3f axis[] = new Vector3f[3];
        geom.getLocalRotation().toAxes(axis);
        directionLeft = axis[0];
        directionUp = axis[1].negateLocal();
        directionFront = axis[2];
        geom.move(walkDirection);
        return null;
      }
    });
  }

  @Override
  public void cleanup()
  {
    super.cleanup();
  }
}
